package com.sd.projectinterface;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.ObjectInputStream;
import java.io.OutputStreamWriter;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.text.DecimalFormat;
import java.util.ArrayList;

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.HttpClient;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.message.BasicNameValuePair;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import objects.CSProb;
import objects.Exp;

import android.annotation.SuppressLint;
import android.app.Activity;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;

@SuppressLint({ "ParserError", "ParserError" })
public class ProblemView extends Activity{
       
        TextView problemDisplay;
        EditText userInput;
        Button checkInput;
        TextView solutionResponse;
        CSProb c;
        int gameId, userId;
        long startTime, totalTime;
        public static final String KEY_120 = "http://10.0.2.2/mathRomp/getProb.php";
        public static final String KEY_121 = "http://10.0.2.2/mathRomp/updateScore.php";
        public static final String KEY_122 = "http://10.0.2.2/mathRomp/getTurn.php";
        public static final String KEY_123 = "http://10.0.2.2/mathRomp/getProbType.php";
        public static final String KEY_124 = "http://10.0.2.2/mathRomp/updateProblem.php";
        public static final String KEY_125 = "http://10.0.2.2/mathRomp/getUserNum.php";
        public static final String KEY_127 = "http://10.0.2.2/mathRomp/updateFastestTime.php";
       
        //@SuppressLint({ "ParserError", "ParserError", "ParserError" })
        @SuppressLint("ParserError")
        @Override
        protected void onCreate(Bundle savedInstanceState){
                super.onCreate(savedInstanceState);
                setContentView(R.layout.problem_view);
                Bundle incoming = this.getIntent().getExtras();
                MyApplication myApp = (MyApplication) getApplicationContext();
                startTime = System.currentTimeMillis();
                totalTime = 0;
                userId = myApp.getId();
                gameId = incoming.getInt("gameId");
                problemDisplay = (TextView) findViewById(R.id.problem);
                userInput = (EditText) findViewById(R.id.user_solution);
                checkInput = (Button) findViewById(R.id.check_input);
                solutionResponse = (TextView) findViewById(R.id.response);
                //solutionResponse.setText("gameId: "+gameId);
               
                //final CSProb c = (CSProb) incoming.get("c");
                c = getProb();
                problemDisplay.setText(c.getProblem());
                //problemDisplay.setText(getProb());
               
                checkInput.setOnClickListener(new View.OnClickListener() {
                        @SuppressLint({ "ParserError", "ParserError", "ParserError", "ParserError", "ParserError", "ParserError", "ParserError", "ParserError" })
                        public void onClick(View v) {
                                DecimalFormat df = new DecimalFormat("#.###");
                                Boolean correct = false;
                                if(c.id == 0){
                                        //Solution is an integer
                                        System.out.println("c's id is 0");
                                        double u = Double.parseDouble(userInput.getText()+"");
                                        double r = Double.parseDouble(df.format(c.getSolution()));
                                        if(u==r){
                                                correct = true;
                                        }
                                }else if(c.id == 1){
                                        //Solution is a fraction
                                        System.out.println("c's id is 1");
                                        String f = userInput.getText()+"";
                                        f = f.replaceAll("\\s", "");
                                        if(f.contains("/")){
                                                int i = f.indexOf("/");
                                                int n = Integer.parseInt(f.substring(0,i));
                                                int d = Integer.parseInt(f.substring(i+1, f.length()));
                                                System.out.println("n: "+n);
                                                System.out.println("d: "+d);
                                                if((n == c.getFSolution().num) && (d == c.getFSolution().denom)){
                                                        correct = true;
                                                }
                                        }else{
                                                double u = Double.parseDouble(userInput.getText()+"");
                                                System.out.println("Frac value: "+u);
                                                double r = Double.parseDouble(df.format(c.getFSolution().value()));
                                                if(u == r){
                                                        correct = true;
                                                }
                                        }
                                }else if(c.id == 2){
                                        //Solution is an exponent
                                        System.out.println("c's id is 2");
                                        String e = userInput.getText()+"";
                                        e = e.replaceAll(" ", "");
                                        if(e.contains("^")){
                                                int i = e.indexOf("^");
                                                int n = Integer.parseInt(e.substring(0, i));
                                                int d = Integer.parseInt(e.substring(i+1, e.length()));
                                                System.out.println("n: "+n);
                                                System.out.println("e: "+e);
                                                if((n == c.getExpSolution().number) && (d == c.getExpSolution().exponent)){
                                                        correct = true;
                                                }
                                        }else{
                                                double u = Double.parseDouble(userInput.getText()+"");
                                                System.out.println("Expo value: "+c.getExpSolution().value());
                                                double r = Double.parseDouble(df.format(c.getExpSolution().value()));
                                                if(u == r){
                                                        correct = true;
                                                }
                                        }
                                }else if(c.id == 3){
                                        //Solution is a list of factors
                                        System.out.println("c's id is 3");
                                        String in = userInput.getText()+"";
                                        int[] f = c.getFactSolution();
                                        if(f.length == 1){
                                                try{
                                                 int u = Integer.parseInt(in);
                                                 if(u == f[0]){
                                                         correct = true;
                                                 }
                                                }catch(NumberFormatException e){
                                                       
                                                }
                                         }else{
                                                 int factorNum = 0;
                                                 int charNum = 0;
                                                 for(int i=0; i<f.length; i++){
                                                         if((i==f.length-1) &&
                                                                         (in.contains(", "+f[i]+"") || in.contains(","+f[i]+""))){
                                                                 factorNum++;
                                                         }else if(in.contains(""+f[i]+",")
                                                                         || in.contains(""+f[i]+", ") || in.contains(""+f[i]+" ,")){
                                                                 factorNum++;
                                                         }
                                                 }
                                                 for(int i=0; i<in.length(); i++){
                                                         if(in.charAt(i) == ','){
                                                                 charNum++;
                                                         }
                                                 }
                                                 if((factorNum == f.length) && (charNum == f.length-1)){
                                                         correct = true;
                                                 }
                                         }
                                }else if(c.id == 4){
                                        //Solution is a string
                                        String u = (userInput.getText()+"").replace(" ", "");
                                        String s;
                                        for(int i=0; i<c.getPropSolution().length; i++){
                                                s = c.getPropSolution()[i].replace(" ", "");
                                                if(u.equals(s)){
                                                        correct = true;
                                                }      
                                        }
                                }
                       
                                if(correct){
                                        solutionResponse.setText("Correct!");
                                        totalTime = System.currentTimeMillis() - startTime;
                                        updateScore();
                                        updateFastestTime();
                                        if(getUserNum() == 1){
                                                getNewProblem();
                                        }
                                        checkInput.setText("Back");
                                        checkInput.setOnClickListener(new View.OnClickListener() {
                                                public void onClick(View v2) {
                                                        Intent i = new Intent(ProblemView.this, MainActivity.class);
                                                        i.putExtra("j", userId);
                                                        startActivity(i);
                                                }
                                        });
                                }else{
                                        solutionResponse.setText("Incorrect");
                                }
                        }
                });
        }
       
       
        @Override
        public boolean onCreateOptionsMenu(Menu menu) {
                getMenuInflater().inflate(R.menu.main, menu);
                return true;
        }
       
        /*public void updateScore(){
        InputStream is = null;
        String result = "";
        ArrayList<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>();
        nameValuePairs.add(new BasicNameValuePair("gameId", gameId+""));
        nameValuePairs.add(new BasicNameValuePair("userId", userId+""));
       
        //http post
        try{
                HttpClient httpclient = new DefaultHttpClient();
                HttpPost httppost = new HttpPost(KEY_121);
                httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs));
                HttpResponse response = httpclient.execute(httppost);
                HttpEntity entity = response.getEntity();
                is = entity.getContent();
        }catch(Exception e){
                Log.e("log_tag", "Error in http connection in updateScore: "+e);
                return;
        }
       
        //convert response to string
        try{
                BufferedReader reader = new BufferedReader(new InputStreamReader(is, "iso-8859-1"),8);
                StringBuilder sb = new StringBuilder();
                String line = null;
                while((line = reader.readLine()) != null){
                        sb.append(line + "\n");
                }
                is.close();
                result = sb.toString();
                System.out.println(result);
        }catch(Exception e){
                Log.e("log_tag", "Error converting result updateScore: "+e);
                return;
        }
    }*/
    
        public void updateScore(){
            InputStream is = null;
            String result = "";
            ArrayList<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>();
            nameValuePairs.add(new BasicNameValuePair("gameId", gameId+""));
            nameValuePairs.add(new BasicNameValuePair("userId", userId+""));
            int inc;
            if(totalTime <= 30000){
            	inc = 3;
            }else if(totalTime <= 60000){
            	inc = 2;
            }else{
            	inc = 1;
            }
            System.out.println("User scored "+inc+" points");
            nameValuePairs.add(new BasicNameValuePair("increment", inc+""));
            
            //http post
            try{
                    HttpClient httpclient = new DefaultHttpClient();
                    HttpPost httppost = new HttpPost(KEY_121);
                    httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs));
                    HttpResponse response = httpclient.execute(httppost);
                    HttpEntity entity = response.getEntity();
                    is = entity.getContent();
            }catch(Exception e){
                    Log.e("log_tag", "Error in http connection in updateScore: "+e);
                    return;
            }
           
            //convert response to string
            try{
                    BufferedReader reader = new BufferedReader(new InputStreamReader(is, "iso-8859-1"),8);
                    StringBuilder sb = new StringBuilder();
                    String line = null;
                    while((line = reader.readLine()) != null){
                            sb.append(line + "\n");
                    }
                    is.close();
                    result = sb.toString();
                    System.out.println(result);
            }catch(Exception e){
                    Log.e("log_tag", "Error converting result updateScore: "+e);
                    return;
            }
        }
        
        public void updateFastestTime(){
            InputStream is = null;
            String result = "";
            System.out.println("Time taken = "+totalTime);
            ArrayList<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>();
            nameValuePairs.add(new BasicNameValuePair("userId", userId+""));
            nameValuePairs.add(new BasicNameValuePair("newTime", totalTime+""));
           
            //http post
            try{
                    HttpClient httpclient = new DefaultHttpClient();
                    HttpPost httppost = new HttpPost(KEY_127);
                    httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs));
                    HttpResponse response = httpclient.execute(httppost);
                    HttpEntity entity = response.getEntity();
                    is = entity.getContent();
            }catch(Exception e){
                    Log.e("log_tag", "Error in http connection in updateFastestTime: "+e);
                    return;
            }
           
            //convert response to string
            try{
                    BufferedReader reader = new BufferedReader(new InputStreamReader(is, "iso-8859-1"),8);
                    StringBuilder sb = new StringBuilder();
                    String line = null;
                    while((line = reader.readLine()) != null){
                            sb.append(line + "\n");
                    }
                    is.close();
                    result = sb.toString();
                    System.out.println(result);
            }catch(Exception e){
                    Log.e("log_tag", "Error converting result updateFastestTime: "+e);
                    return;
            }
        }
       
        @SuppressLint({ "ParserError", "ParserError" })
        public CSProb getProb(){
        InputStream is = null;
        String result = "";
        ArrayList<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>();
        nameValuePairs.add(new BasicNameValuePair("gameId", gameId+""));
       
        //http post
        try{
                HttpClient httpclient = new DefaultHttpClient();
                HttpPost httppost = new HttpPost(KEY_120);
                httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs));
                HttpResponse response = httpclient.execute(httppost);
                HttpEntity entity = response.getEntity();
                is = entity.getContent();
        }catch(Exception e){
                Log.e("log_tag", "Error in http connection in getProb: "+e);
                return null;
        }
       
        //convert response to string
        try{
                BufferedReader reader = new BufferedReader(new InputStreamReader(is, "iso-8859-1"),8);
                StringBuilder sb = new StringBuilder();
                String line = null;
                while((line = reader.readLine()) != null){
                        sb.append(line + "\n");
                }
                is.close();
                result = sb.toString();
                System.out.println(result);
        }catch(Exception e){
                Log.e("log_tag", "Error converting result in getProb: "+e);
                return null;
        }
       
        //parse json data
        JSONArray jArray = null;
        JSONObject prob = null;
        String jInfo;
        try{
                jArray = new JSONArray(result);
                JSONObject json_data = jArray.getJSONObject(0);
                System.out.println("json_data: "+json_data);
                jInfo = json_data.getString("currentProb");
                String d = "\\";
                jInfo = jInfo.replace(d, "");
                //jInfo = jInfo.replace(" ","");
                System.out.println("jInfo: "+jInfo);
                prob = new JSONObject(jInfo);
        }catch(JSONException e){
                Log.e("log_tag", "Error parsing data in getProb: "+e);
                return null;
        }
        try {
                int probId = prob.getInt("id");
                System.out.println("prob.id: "+probId);
                if(probId == 0){
                        return new CSProb(prob.getString("currentProblem"), prob.getDouble("solution"));
                }else if(probId == 1){
                        return new CSProb(prob.getString("currentProblem"), prob.getInt("fracSolutionNum"), prob.getInt("fracSolutionDenom"));
                }else if(probId == 2){
                        return new CSProb(prob.getString("currentProblem"), new Exp(prob.getInt("expSolutionNum"), prob.getInt("expSolutionExp")));
                }else if(probId == 3){
                        JSONArray jsonFactors = prob.getJSONArray("factSolution");
                        int[] factors = new int[jsonFactors.length()];
                        for(int i=0; i<factors.length; i++){
                                factors[i] = jsonFactors.getJSONObject(i).getInt("factor");
                        }
                        return new CSProb(prob.getString("currentProblem"), factors);
                }else if(probId == 4){
                        JSONArray jsonProps = prob.getJSONArray("propSolution");
                        String[] props = new String[jsonProps.length()];
                        for(int i=0; i<props.length; i++){
                                props[i] = jsonProps.getJSONObject(i).getString("prop");
                        }
                        return new CSProb(prob.getString("currentProblem"), props);
                }
                        return null;
                } catch (JSONException e) {
                        System.out.println("prob: "+prob);
                        return null;
                }
    }
       
        public void getNewProblem(){
                String probType = "";
                int gramType;
                InputStream is = null;
        String result = "";
        ArrayList<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>();
        nameValuePairs.add(new BasicNameValuePair("gameId", gameId+""));
       
        //http post
        try{
                HttpClient httpclient = new DefaultHttpClient();
                HttpPost httppost = new HttpPost(KEY_123);
                httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs));
                HttpResponse response = httpclient.execute(httppost);
                HttpEntity entity = response.getEntity();
                is = entity.getContent();
        }catch(Exception e){
                Log.e("log_tag", "Error in http connection in getNewProblem: "+e);
                return;
        }
       
        //convert response to string
        try{
                BufferedReader reader = new BufferedReader(new InputStreamReader(is, "iso-8859-1"),8);
                StringBuilder sb = new StringBuilder();
                String line = null;
                while((line = reader.readLine()) != null){
                        sb.append(line + "\n");
                }
                is.close();
                result = sb.toString();
                System.out.println(result);
        }catch(Exception e){
                Log.e("log_tag", "Error converting result in getNewProblem: "+e);
                return;
        }
       
        //parse json data
        JSONArray jArray = null;
        try{
                jArray = new JSONArray(result);
                JSONObject json_data = jArray.getJSONObject(0);
                System.out.println("json_data: "+json_data);
                probType = json_data.getString("subject");
                gramType = json_data.getInt("gramType");
        }catch(JSONException e){
                Log.e("log_tag", "Error parsing data in getNewProblem: "+e);
                return;
        }
                System.out.println("Subject is: "+probType+" and gramType = "+gramType);
                Socket s = null;
                try {
                        InetSocketAddress sa;
                        if (gramType == 0) {
                                sa = new InetSocketAddress("10.0.2.2", 8884);
                        } else {
                                sa = new InetSocketAddress("10.0.2.2", 8886);
                        }
                        s = new Socket();
                        s.connect(sa, 2000);
                        OutputStreamWriter osw = new OutputStreamWriter(s
                                        .getOutputStream());
                        osw.write(probType + "\n");
                        osw.flush();
                        ObjectInputStream isr = new ObjectInputStream(s
                                        .getInputStream());
                       
                        CSProb newProb = null;
                        try {
                                newProb = (CSProb) isr.readObject();
                                System.out.println("New Prob: "+newProb.probToJson());
                                updateProblem(newProb.probToJson());
                        } catch (ClassNotFoundException e) {
                                System.out.println("c cannot be created: " + e);
                                e.printStackTrace();
                        }
                        isr.close();
                       
                } catch (IOException ioe) {
                        Log.e("Code Error", ioe.getMessage());
                }
        }
       
        public void updateProblem(String prob){
                InputStream is = null;
        String result = "";
        ArrayList<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>();
        nameValuePairs.add(new BasicNameValuePair("prob", prob));
        nameValuePairs.add(new BasicNameValuePair("gameId", gameId+""));
       
        //http post
        try{
                HttpClient httpclient = new DefaultHttpClient();
                HttpPost httppost = new HttpPost(KEY_124);
                httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs));
                HttpResponse response = httpclient.execute(httppost);
                HttpEntity entity = response.getEntity();
                is = entity.getContent();
        }catch(Exception e){
                Log.e("log_tag", "Error in http connection in updateProblem: "+e);
                return;
        }
       
        //convert response to string
        try{
                BufferedReader reader = new BufferedReader(new InputStreamReader(is, "iso-8859-1"),8);
                StringBuilder sb = new StringBuilder();
                String line = null;
                while((line = reader.readLine()) != null){
                        sb.append(line + "\n");
                }
                is.close();
                result = sb.toString();
                System.out.println(result);
        }catch(Exception e){
                Log.e("log_tag", "Error converting result in updateProblem: "+e);
                return;
        }
        }
       
        @SuppressLint({ "ParserError", "ParserError" })
        public int getUserNum() {
                InputStream is = null;
                String result = "";
                ArrayList<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>();
                nameValuePairs.add(new BasicNameValuePair("gameId", gameId + ""));
                nameValuePairs.add(new BasicNameValuePair("userId", userId+""));

                // http post
                try {
                        HttpClient httpclient = new DefaultHttpClient();
                        HttpPost httppost = new HttpPost(KEY_125);
                        httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs));
                        HttpResponse response = httpclient.execute(httppost);
                        HttpEntity entity = response.getEntity();
                        is = entity.getContent();
                } catch (Exception e) {
                        Log.e("log_tag", "Error in http connection in getUserNum: " + e);
                        return -1;
                }

                // convert response to string
                try {
                        BufferedReader reader = new BufferedReader(new InputStreamReader(
                                        is, "iso-8859-1"), 8);
                        StringBuilder sb = new StringBuilder();
                        String line = null;
                        while ((line = reader.readLine()) != null) {
                                sb.append(line + "\n");
                        }
                        is.close();
                        result = sb.toString();
                        System.out.println(result);
                } catch (Exception e) {
                        Log.e("log_tag", "Error converting result in getUserNum: " + e);
                        return -1;
                }

                // parse json data
                JSONArray jArray = null;
                try {
                        jArray = new JSONArray(result);
                        JSONObject json_data = jArray.getJSONObject(0);
                        return json_data.getInt("userNum");
                } catch (JSONException e) {
                        Log.e("log_tag", "Error parsing data in getUserNum: " + e);
                        return -1;
                }
   
        }
}
